home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / info-service / gopher / Unix / xvgopher / v0.5beta / xvgopher.shar.01 < prev    next >
Encoding:
Text File  |  1993-03-26  |  53.8 KB  |  2,086 lines

  1. ---- Cut Here and feed the following to sh ----
  2. #!/bin/sh
  3. # This is a shell archive (shar 3.47)
  4. # made 03/26/1993 20:19 UTC by turtle@hercules
  5. # Source directory /usr/local/src/public_domain/tools/xvgopher
  6. #
  7. # existing files will NOT be overwritten unless -c is specified
  8. #
  9. # This shar contains:
  10. # length  mode       name
  11. # ------ ---------- ------------------------------------------
  12. #   6152 -rw-rw-r-- README
  13. #   1084 -rw-rw-r-- COPYRIGHT
  14. #    199 -rw-rw-r-- BUGS
  15. #    169 -rw-rw-r-- TODO
  16. #   3684 -rw-r--r-- Makefile
  17. #   2170 -rw-rw-r-- xvgopher.man
  18. #   8558 -rw-r--r-- Connection.cc
  19. #   5530 -rw-rw-r-- GWAbout.cc
  20. #    498 -rw-r--r-- GWBinary.cc
  21. #   8907 -rw-rw-r-- GWBookmarks.cc
  22. #   9592 -rw-rw-r-- GWDirectory.cc
  23. #   7644 -rw-r--r-- GWDownload.cc
  24. #   5861 -rw-rw-r-- GWFile.cc
  25. #   2602 -rw-rw-r-- GWGopher.cc
  26. #    472 -rw-r--r-- GWImage.cc
  27. #   2924 -rw-r--r-- GWIndex.cc
  28. #   1679 -rw-r--r-- GWInfo.cc
  29. #   8870 -rw-rw-r-- GWList.cc
  30. #   4701 -rw-r--r-- GWPref.cc
  31. #    469 -rw-r--r-- GWSound.cc
  32. #   1331 -rw-r--r-- GWTelnet.cc
  33. #   7751 -rw-rw-r-- GWindow.cc
  34. #   8621 -rw-rw-r-- Gopher.cc
  35. #   1821 -rw-r--r-- List.cc
  36. #   5632 -rw-rw-r-- Preferences.cc
  37. #   2479 -rw-r--r-- Response.cc
  38. #   3627 -rw-r--r-- cursor.cc
  39. #   2754 -rw-rw-r-- icons.cc
  40. #    996 -rw-rw-r-- main.cc
  41. #    486 -rw-r--r-- Config.h
  42. #   1949 -rw-r--r-- Connection.h
  43. #    620 -rw-r--r-- GWAbout.h
  44. #    417 -rw-r--r-- GWBinary.h
  45. #   1124 -rw-r--r-- GWBookmarks.h
  46. #   1210 -rw-rw-r-- GWDirectory.h
  47. #    966 -rw-r--r-- GWDownload.h
  48. #    481 -rw-r--r-- GWFile.h
  49. #    646 -rw-rw-r-- GWGopher.h
  50. #    411 -rw-r--r-- GWImage.h
  51. #    503 -rw-r--r-- GWIndex.h
  52. #    569 -rw-r--r-- GWInfo.h
  53. #   1107 -rw-rw-r-- GWList.h
  54. #    860 -rw-r--r-- GWPref.h
  55. #    411 -rw-r--r-- GWSound.h
  56. #    458 -rw-r--r-- GWTelnet.h
  57. #   1931 -rw-rw-r-- GWindow.h
  58. #   1608 -rw-r--r-- Gopher.h
  59. #    771 -rw-r--r-- List.h
  60. #   1892 -rw-r--r-- Object.h
  61. #   1347 -rw-r--r-- Preferences.h
  62. #   2963 -rw-r--r-- Response.h
  63. #   1684 -rw-r--r-- String.h
  64. #    241 -rw-r--r-- cursor.h
  65. #    248 -rw-r--r-- icons.h
  66. #   2810 -rw-rw-r-- xvgopher.h
  67. #    222 -rw-r--r-- icons/bin
  68. #    222 -rw-r--r-- icons/cso
  69. #    222 -rw-r--r-- icons/dir
  70. #    222 -rw-r--r-- icons/doc
  71. #    222 -rw-r--r-- icons/dos
  72. #    222 -rw-r--r-- icons/error
  73. #   2190 -rw-r--r-- icons/gopher.icon
  74. #   2190 -rw-r--r-- icons/gopher.icon.mask
  75. #   2190 -rw-r--r-- icons/gopher1
  76. #   2190 -rw-r--r-- icons/gopher1.mask
  77. #   2190 -rw-r--r-- icons/gopher2
  78. #   2190 -rw-r--r-- icons/gopher2.mask
  79. #    222 -rw-r--r-- icons/idx
  80. #    222 -rw-r--r-- icons/image
  81. #    222 -rw-r--r-- icons/info
  82. #    222 -rw-r--r-- icons/info_dragging
  83. #    222 -rw-r--r-- icons/mac
  84. #    222 -rw-r--r-- icons/sound
  85. #    222 -rw-r--r-- icons/tel
  86. #    222 -rw-r--r-- icons/unknown
  87. #    222 -rw-r--r-- icons/uu
  88. #
  89. # ============= README ==============
  90. if test -f 'README' -a X"$1" != X"-c"; then
  91.     echo 'x - skipping README (File already exists)'
  92. else
  93. echo 'x - extracting README (Text)'
  94. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  95. README
  96. X
  97. This is a beta release of xvgopher -- an XView based gopher client.
  98. X
  99. Gopher is a distributed information browsing/retrieval system used at
  100. many universities and other institutions to make information and
  101. services available in a user friendly and consistent manner.
  102. X
  103. NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  104. This is a beta release!  This means that I am still very actively working
  105. on xvgopher, but I got many requests to make it available ASAP.
  106. Please report any problems you find as soon as possible so that I can
  107. incorporate the fixes in the first major release.
  108. The latest release will always be available.  There are two ways of
  109. accessing it:
  110. X
  111. X    anonymous ftp to gopher.sdsu.edu in /pub/xvgopher
  112. X    gopher to gopher.sdsu.edu: Software Distribution/UNIX/XvGopher
  113. X
  114. X
  115. HISTORY OF XVGOPHER
  116. We started out wanting something similar to TurboGopher (a Macintosh
  117. gopher client.  Really nice!!) for MS-Windows.  There are several good
  118. pc gopher clients available, but the ones I checked out either didn't
  119. run as a MS-Windows application, weren't public domain, or required
  120. some non- public domain networking software.  (We are on an extreemly
  121. low budget...) So, we decided to write one...
  122. X
  123. Well, this would have been great, but I refused to write any MS-Windows
  124. applications on my 20 MHz 386!  So, while waiting for a better PC, I
  125. decided I might as well write a prototype using XView.
  126. X
  127. I should point out that there is a pretty nice X11 gopher client
  128. available called xgopher.  However, it boils down to a fancy window
  129. around something similar to the text based gopher client.  (This is
  130. greatly exaggerated, of course!)  We did use the gopher icon that
  131. xgopher uses.  It is pretty cute (and none of us are good artists.)
  132. X
  133. The prototype I started writing turned out to be quite usable and we
  134. started using it instead of the text based client.  It is not a
  135. prototype anymore; it is now a full gopher client.
  136. X
  137. I wrote all of xvgopher in C++ because that is the language I am most
  138. comfortable with.  I used the Sniff C++ development system to write
  139. all the code and I used Sun's DevGuide to figure out sizes of windows and
  140. locations of buttons.  I did not use DevGuide for the code generation
  141. for several reasons:  1) Not everyone has DevGuide which makes it hard
  142. to distribute the source code.  2) The C++ code generator that comes with
  143. DevGuide doesn't really do anything in an object oriented way.  It would
  144. make the code horrible!  (Actually, XView is not very easy to integrate
  145. in an object oriented program because of all the callbacks...)
  146. X
  147. X
  148. SYSTEM REQUIREMENTS
  149. xvgopher is written in C++.  This may scare some people, but not to
  150. worry.  If you do not have a C++ compiler, just get gcc 2.3.3 and
  151. libg++.  xvgopher will compile with those just fine.  So far it has
  152. been tested on various suns running SunOS 4.1.X and on an HP 750.
  153. The code does not use any C++ features not available in cfront 2.1.  So
  154. if your C++ compiler does not support templates....  neither does
  155. ours!!!  (We only just got SunPRO's C++ 3.0 compiler.  Thanks for the
  156. great 15 minute license linger time, SunPRO!!!!! :-(  Stuff like that
  157. doesn't work in a University environment!  (ANDREW!!!  GET OFF THAT
  158. SOAP BOX!!!)) xvgopher also requires that you have XView3 installed on
  159. your system.  If you have Sun's Openwin 3.0, that's fine too, although
  160. you will have to have the 'Openwin Programmers' section installed.  The
  161. only other requirement is that you have to have some network so you can
  162. talk to a gopher server.
  163. X
  164. X
  165. CONFIGURING
  166. Configuring xvgopher is pretty straight forward.  Just edit
  167. 'xvgopher.h' and change the defines above the section that says to not
  168. edit anything below it.  (Did I make you read that sentence twice??
  169. :-)) Then edit the Makefile and change the macros to your liking.
  170. X
  171. X
  172. COMPILING & LINKING
  173. Type 'make depend'
  174. Type 'make'
  175. X
  176. X
  177. INSTALLING
  178. type 'make install'
  179. It will install the xvgopher executable and the man page.
  180. X
  181. X
  182. USER CONFIGURATION
  183. The first time xvgopher is run by a user, it creates ~/.xvgopher-defaults.
  184. This file contains all the currently configurable items.  The easiest
  185. is to change those parameters using the Preferences popup, but they can
  186. also be edited by hand.  Xvgopher uses the X11 resource database
  187. routines to read the items, so the format of the file should be
  188. familiar.  When bookmarks are created, a file called ~/.xvgopher-bm
  189. will be created which contains a list of bookmarks.  The bookmarks are
  190. stored in the same way they information was sent from a gopher server
  191. to xvgopher.  If you are not familiar with the gopher protocol, don't
  192. worry about it.  If you ARE familiar with the gopher protocol, don't
  193. worry about it too much.
  194. X
  195. CREDITS
  196. (These really should be slowly scrolling by while appropriate music
  197. is playing, but you have to wait for version 427 for that feature...)
  198. Thanks to all the people who have done testing and given me feedback
  199. on the design and implementation of xvgopher.  
  200. Here are some names:
  201. X
  202. Mark Boyns (SDSU)            -- testing & UI layout & icons
  203. John Denune (SDSU)            -- testing
  204. Mike Halderman (NOSC)            -- testing
  205. Paul Lindner (UMN)            -- gopher icon
  206. X
  207. X
  208. BUGS, COMMENTS, GRIPES, MONEY, LOVE
  209. If you have any of the above directed at me, I'd like to hear about
  210. it!  I would especially welcome any bug reports (and possible fixes)
  211. and also comments.  I like getting email!
  212. Basically, if you like it, let me know why.
  213. If you dislike it, let me know why.
  214. If you had problems, let me know why.
  215. If you have not tried xvgopher but still have comments about it, let me
  216. know why.
  217. If you don't like me, let me know why.
  218. If you think this is getting silly, let me know why.
  219. If you are still reading this list of questions, you owe me beer!!!
  220. X
  221. X
  222. WHERE IS ANDREW??
  223. Well, I am reachable by email at turtle@sciences.sdsu.edu
  224. X
  225. Happy gophering to y'all!  C++'ya in gopherspace.
  226. X
  227. X
  228. --Andrew
  229. ____________________________________________________________________________
  230. Andrew "Race Turtle" Scherpbier, SysMgr
  231. College of Sciences
  232. San Diego State University
  233. EMAIL:    turtle@sciences.sdsu.edu
  234. VOICE:    (619) 594-5026
  235. FAX:    (619) 594-6381
  236. ____________________________________________________________________________
  237. SHAR_EOF
  238. chmod 0664 README ||
  239. echo 'restore of README failed'
  240. Wc_c="`wc -c < 'README'`"
  241. test 6152 -eq "$Wc_c" ||
  242.     echo 'README: original size 6152, current size' "$Wc_c"
  243. fi
  244. # ============= COPYRIGHT ==============
  245. if test -f 'COPYRIGHT' -a X"$1" != X"-c"; then
  246.     echo 'x - skipping COPYRIGHT (File already exists)'
  247. else
  248. echo 'x - extracting COPYRIGHT (Text)'
  249. sed 's/^X//' << 'SHAR_EOF' > 'COPYRIGHT' &&
  250. This software is Copyright 1993, San Diego State University -- College
  251. of Sciences
  252. X
  253. ------------------------------------------------------------------------
  254. WARRANTY DISCLAIMER
  255. X
  256. This software was created by Andrew Scherpbier at San Diego State
  257. University and is distributed free of charge.  It is placed in the
  258. public domain and permission is granted to anyone to use, duplicate,
  259. modify and redistribute it provided that this notice is attached and
  260. that the modified sources are sent back to San Diego State University.
  261. X
  262. San Diego State University and Andrew Scherpbier provide absolutely NO
  263. WARRANTY OF ANY KIND with respect to this software.  The entire risk as
  264. to the quality and performance of this software is with the user.  IN
  265. NO EVENT WILL SAN DIEGO STATE UNIVERSITY OR ANDREW SCHERPBIER BE LIABLE
  266. TO ANYONE FOR ANY DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE,
  267. INCLUDING, WITHOUT LIMITATION, DAMAGES RESULTING FROM LOST DATA OR LOST
  268. PROFITS, OR FOR ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES.
  269. ------------------------------------------------------------------------
  270. SHAR_EOF
  271. chmod 0664 COPYRIGHT ||
  272. echo 'restore of COPYRIGHT failed'
  273. Wc_c="`wc -c < 'COPYRIGHT'`"
  274. test 1084 -eq "$Wc_c" ||
  275.     echo 'COPYRIGHT: original size 1084, current size' "$Wc_c"
  276. fi
  277. # ============= BUGS ==============
  278. if test -f 'BUGS' -a X"$1" != X"-c"; then
  279.     echo 'x - skipping BUGS (File already exists)'
  280. else
  281. echo 'x - extracting BUGS (Text)'
  282. sed 's/^X//' << 'SHAR_EOF' > 'BUGS' &&
  283. Known bugs.
  284. X
  285. Version 1.0 (March, 1993)
  286. X
  287. 1    'Another gopher...' pops up two windows for some reason.
  288. 2    Sometimes, when double clicking on multiple items, some of the
  289. X    windows will never become unbusy.
  290. SHAR_EOF
  291. chmod 0664 BUGS ||
  292. echo 'restore of BUGS failed'
  293. Wc_c="`wc -c < 'BUGS'`"
  294. test 199 -eq "$Wc_c" ||
  295.     echo 'BUGS: original size 199, current size' "$Wc_c"
  296. fi
  297. # ============= TODO ==============
  298. if test -f 'TODO' -a X"$1" != X"-c"; then
  299.     echo 'x - skipping TODO (File already exists)'
  300. else
  301. echo 'x - extracting TODO (Text)'
  302. sed 's/^X//' << 'SHAR_EOF' > 'TODO' &&
  303. Things I still need to add to xvgopher.
  304. X
  305. +    Timeouts for network activities
  306. X
  307. +    Support for CSO phonebook searches
  308. X
  309. +    More flexible configuration
  310. X
  311. +    Hierarchal bookmarks
  312. X
  313. SHAR_EOF
  314. chmod 0664 TODO ||
  315. echo 'restore of TODO failed'
  316. Wc_c="`wc -c < 'TODO'`"
  317. test 169 -eq "$Wc_c" ||
  318.     echo 'TODO: original size 169, current size' "$Wc_c"
  319. fi
  320. # ============= Makefile ==============
  321. if test -f 'Makefile' -a X"$1" != X"-c"; then
  322.     echo 'x - skipping Makefile (File already exists)'
  323. else
  324. echo 'x - extracting Makefile (Text)'
  325. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  326. #
  327. # Makefile for xvgopher.
  328. #
  329. # (c) Copyright 1993, San Diego State University -- College of Sciences
  330. #       (See the COPYRIGHT file for more Copyright information)
  331. #
  332. # This makefile will work on standard Sun4 systems running SunOS 4.1.X
  333. # and which have the Sun C++ compiler installed in /usr/lang
  334. # If your configuration differs, you will have to modify the rest of this
  335. # file.
  336. #
  337. # The directory the executable should be installed in
  338. BINDIR    =    /usr/local/bin
  339. X
  340. #
  341. # The directory where the man page should go
  342. MANDIR    =    /usr/local/man
  343. X
  344. #
  345. # The section to use for the man page.
  346. MANSECT    =    l
  347. X
  348. #
  349. # Compiler to use.  It has been tested with Sun C++ 2.0, g++ 2.3.3, and
  350. # Sun C++ 3.0
  351. #CCC    =    CC
  352. #CCC    =    g++ -fno-strict-prototypes -w
  353. CCC    =    /usr/local/lang/CC
  354. X
  355. #
  356. # Flags for the compiler.  We use openwin for our X development, but
  357. # the standard x11r5/xview3 will work just fine.
  358. #
  359. CCFLAGS    =    -I$(OPENWINHOME)/include -O
  360. X
  361. #
  362. # I specified the openwin libraries specifically to get around some
  363. # problems with people not mounting our x11r5 tree.  Using this overrides
  364. # the LD_LIBRARY_PATH environment and makes the shared version work on
  365. # all machines with openwin3
  366. #
  367. LDFLAGS    =    -g -L/usr/openwin/lib
  368. X
  369. #
  370. # The makedepend looks in the 'standard' places for system include files.
  371. # Well, Sun decided they weren't going to use the 'standard' places for
  372. # their compilers, so we have to specifiy the actual path...  (Bogus!!!)
  373. #
  374. SYS_INCLUDES =    -I/usr/lang/SC1.0/include/CC
  375. #SYS_INCLUDES =    -I/usr/local/gnu/lib/g++-include -I/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1.2/2.3.3/include
  376. X
  377. #
  378. # Strangely enough xvgopher uses xview!!!
  379. #
  380. LIBS    =    -lxview -lolgx -lX11
  381. X
  382. #
  383. # All the files which will end up with an object file.  (Can't just say
  384. # all source files, because in C++ the headers can contain all kinds of
  385. # source as well...)
  386. #
  387. SRCS    =    \
  388. X        Connection.cc \
  389. X        GWAbout.cc \
  390. X        GWBinary.cc \
  391. X        GWBookmarks.cc \
  392. X        GWDirectory.cc \
  393. X        GWDownload.cc \
  394. X        GWFile.cc \
  395. X        GWGopher.cc \
  396. X        GWImage.cc \
  397. X        GWIndex.cc \
  398. X        GWInfo.cc \
  399. X        GWList.cc \
  400. X        GWPref.cc \
  401. X        GWSound.cc \
  402. X        GWTelnet.cc \
  403. X        GWindow.cc \
  404. X        Gopher.cc \
  405. X        List.cc \
  406. X        Preferences.cc \
  407. X        Response.cc \
  408. X        cursor.cc \
  409. X        icons.cc \
  410. X        main.cc
  411. X
  412. #
  413. # I am lazy.  I hate typing in lists into makefiles!  I think the word
  414. # replacement macro in makefiles is the best thing since sliced cheese!
  415. #
  416. OBJS    =    $(SRCS:%.cc=%.o)
  417. X
  418. #
  419. # The list of files to put in the shar archive
  420. #
  421. SHARFILES =    \
  422. X        README \
  423. X        COPYRIGHT \
  424. X        BUGS \
  425. X        TODO \
  426. X        Makefile \
  427. X        xvgopher.man \
  428. X        $(SRCS) \
  429. X        *.h \
  430. X        icons/*
  431. X
  432. TARGET    =    xvgopher
  433. X
  434. all:        $(TARGET)
  435. X
  436. $(TARGET):    $(OBJS)
  437. X    $(CCC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
  438. X
  439. static:        $(OBJS)
  440. X    $(CCC) $(LDFLAGS) -o $(TARGET).static $(OBJS) -Bstatic $(LIBS)
  441. X
  442. clean:
  443. X    rm -f $(OBJS) $(TARGET) *.bak *.BAK
  444. X
  445. #
  446. # The installation of the program.
  447. #
  448. install: $(TARGET)
  449. X    install -s $(TARGET) $(BINDIR)
  450. X    install xvgopher.man $(MANDIR)/man$(MANSECT)/xvgopher.$(MANSECT)
  451. X
  452. #
  453. # I use makedepend.  If you don't have it, get it!
  454. #
  455. depend:
  456. X    makedepend -- $(CCFLAGS) $(SYS_INCLUDES) -- $(SRCS)
  457. X
  458. #
  459. # Create a shar file suitable for posting
  460. #
  461. shar:
  462. X    shar -c -o xvgopher.shar -l55 $(SHARFILES)
  463. X
  464. #
  465. # Create some tar files suitable for ftping.
  466. #
  467. tar:
  468. X    gnutar czvf xvgopher.tar.z $(SHARFILES)
  469. X    gnutar cZvf xvgopher.tar.Z $(SHARFILES)
  470. X
  471. zeus:
  472. X    gnutar czvf /tmp/xvg.tar.Z *.cc *.h Makefile icons/*
  473. X    rcp /tmp/xvg.tar.Z zeus:
  474. X    rm /tmp/xvg.tar.Z
  475. X
  476. kiwi:
  477. X    gnutar czvf /tmp/xvg.tar.Z *.cc *.h Makefile icons/*
  478. X    rcp /tmp/xvg.tar.Z kiwi:
  479. X    rm /tmp/xvg.tar.Z
  480. X
  481. rohan:
  482. X    gnutar czvf /tmp/xvg.tar.Z *.cc *.h Makefile icons/*
  483. X    rcp /tmp/xvg.tar.Z rohan:
  484. X    rm /tmp/xvg.tar.Z
  485. X
  486. saturn:
  487. X    gnutar czvf /tmp/xvg.tar.Z *.cc *.h Makefile icons/*
  488. X    rcp /tmp/xvg.tar.Z saturn:
  489. X    rm /tmp/xvg.tar.Z
  490. SHAR_EOF
  491. chmod 0644 Makefile ||
  492. echo 'restore of Makefile failed'
  493. Wc_c="`wc -c < 'Makefile'`"
  494. test 3684 -eq "$Wc_c" ||
  495.     echo 'Makefile: original size 3684, current size' "$Wc_c"
  496. fi
  497. # ============= xvgopher.man ==============
  498. if test -f 'xvgopher.man' -a X"$1" != X"-c"; then
  499.     echo 'x - skipping xvgopher.man (File already exists)'
  500. else
  501. echo 'x - extracting xvgopher.man (Text)'
  502. sed 's/^X//' << 'SHAR_EOF' > 'xvgopher.man' &&
  503. .TH xvgopher l "25 March 1993"
  504. .SH NAME
  505. xvgopher \- XView gopher client program
  506. .SH SYNOPSIS
  507. xvgopher [ 
  508. .I servername
  509. [
  510. .I port#
  511. ] ]
  512. .SH DESCRIPTION
  513. .B Xvgopher
  514. is a user friendly gopher client.
  515. When started,
  516. .B xvgopher
  517. will show the root directory of the gopher server
  518. which was selected when it was compiled.
  519. The type of each item in the list is indicated my a small icon.
  520. The meaning of the icons should be pretty clear, but if you can draw
  521. better icons, send them to me!!!
  522. To activate an item, just double click on it.
  523. .LP
  524. The Gopher menu in the main window contains several useful items:
  525. .TP 8
  526. \(bu Bookmarks...
  527. This will create a window showing your your bookmarks.
  528. .TP 8
  529. \(bu Another Gopher...
  530. This will allow you to contact another gopher server.
  531. You can specify both the server name and the port number.
  532. .TP 8
  533. \(bu Preferences...
  534. This will create a window which allows you to modify things like the
  535. commands to execute for certain things.
  536. .TP 8
  537. \(bu About...
  538. This will create a window showing who created
  539. .B Xvgopher
  540. .SH OPTIONS
  541. By default,
  542. .B xvgopher
  543. will contact whatever server it was compiled with.
  544. If a
  545. .I servername
  546. is specified,
  547. .B xvgopher
  548. will try to contact that server at port 70.
  549. You can modify the port number of the remote server by also specifying
  550. .I port#
  551. .SH FILES
  552. .TP 25
  553. .B $HOME/.xvgopher-defaults
  554. defaults in .Xdefaults format
  555. .TP 25
  556. .B $HOME/.xvgopher-bm
  557. bookmarks as the gopher server would want them
  558. .SH SEE ALSO
  559. gopher(l), xgopher(l)
  560. .SH NOTES
  561. .B Xvgopher
  562. does not currently support the CSO phone book servers.
  563. .SH BUGS
  564. There are no bugs! Maybe some undocumented features, but no bugs...  :-)
  565. .LP
  566. In the unlikely event that you do find a problem or if you have suggestions
  567. on how to improve
  568. .B xvgopher,
  569. send mail to
  570. .B xvgopher@gopher.sdsu.edu
  571. .SH CREDITS
  572. .TP 8
  573. Programmer:
  574. .B "Andrew Scherpbier"
  575. .TP 8
  576. Icons:
  577. .B "Paul Lindner"
  578. did the original gopher icon.
  579. .B "Mark Boyns"
  580. did all the small icons and made the gopher chew.
  581. .TP 8
  582. Layout:
  583. .B "Andrew Scherpbier"
  584. and
  585. .B "Mark Boyns"
  586. with input from many other testers.
  587. .TP 8
  588. Testing:
  589. .B "Mark Boyns,"
  590. .B "John Denune,"
  591. .B "Bob Cademy,"
  592. .B "Mike Halderman,"
  593. and many other guinea pigs.
  594. SHAR_EOF
  595. chmod 0664 xvgopher.man ||
  596. echo 'restore of xvgopher.man failed'
  597. Wc_c="`wc -c < 'xvgopher.man'`"
  598. test 2170 -eq "$Wc_c" ||
  599.     echo 'xvgopher.man: original size 2170, current size' "$Wc_c"
  600. fi
  601. # ============= Connection.cc ==============
  602. if test -f 'Connection.cc' -a X"$1" != X"-c"; then
  603.     echo 'x - skipping Connection.cc (File already exists)'
  604. else
  605. echo 'x - extracting Connection.cc (Text)'
  606. sed 's/^X//' << 'SHAR_EOF' > 'Connection.cc' &&
  607. //
  608. // Connection.cc
  609. //
  610. // (c) Copyright 1993, San Diego State University -- College of Sciences
  611. //       (See the COPYRIGHT file for more Copyright information)
  612. //
  613. // Implementation of the Connection class
  614. //
  615. X
  616. #include "Connection.h"
  617. #include <errno.h>
  618. #include <stdio.h>
  619. #include <sys/types.h>
  620. #include <sys/socket.h>
  621. #include <netinet/in.h>
  622. #include <sys/ioctl.h>
  623. #include <unistd.h>
  624. X
  625. X
  626. Connection::Connection()
  627. {
  628. X    sock = -1;
  629. X    pos = pos_max = 0;
  630. }
  631. X
  632. X
  633. //*************************************************************************
  634. // Connection::Connection(int socket)
  635. // PURPOSE:
  636. //   Create a connection from just a socket.
  637. // PARAMETERS:
  638. //   int socket:  obvious!!!!
  639. //
  640. Connection::Connection(int socket)
  641. {
  642. X    sock = socket;
  643. X
  644. X    int length = sizeof(server);
  645. X    if (getpeername(socket, (struct sockaddr *)&server, &length) < 0)
  646. X    {
  647. X        perror("getpeername");
  648. X    }
  649. X    pos = pos_max = 0;
  650. }
  651. X
  652. X
  653. Connection::~Connection()
  654. {
  655. X    this->close();
  656. }
  657. X
  658. X
  659. int Connection::open(int priv)
  660. {
  661. X    if (priv)
  662. X    {
  663. X        int    aport = IPPORT_RESERVED - 1;
  664. X
  665. X        sock = rresvport(&aport);
  666. X    }
  667. X    else
  668. X        sock = socket(AF_INET, SOCK_STREAM, 0);
  669. X
  670. X    if (sock == NOTOK)
  671. X        return NOTOK;
  672. X
  673. X    int    on = 1;
  674. X    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
  675. X    server.sin_family = AF_INET;
  676. X
  677. X    pos = pos_max = 0;
  678. X    return OK;
  679. }
  680. X
  681. X
  682. int Connection::close()
  683. {
  684. X    if (sock >= 0)
  685. X    {
  686. X        int ret = ::close(sock);
  687. X        sock = -1;
  688. X        return ret;
  689. X    }
  690. X    return NOTOK;
  691. }
  692. X
  693. X
  694. int Connection::assign_port(int port)
  695. {
  696. X    server.sin_port = htons(port);
  697. X    return OK;
  698. }
  699. X
  700. X
  701. int Connection::assign_port(char *service)
  702. {
  703. X    struct servent        *sp;
  704. X
  705. X    sp = getservbyname(service, "tcp");
  706. X    if (sp == NULL)
  707. X    {
  708. X        return NOTOK;
  709. X    }
  710. X    server.sin_port = sp->s_port;
  711. X    return OK;
  712. }
  713. X
  714. int Connection::assign_server(dword addr)
  715. {
  716. X    server.sin_addr.s_addr = addr;
  717. X    return OK;
  718. }
  719. X
  720. int Connection::assign_server(char *name)
  721. {
  722. X    struct hostent        *hp;
  723. X
  724. X    hp = gethostbyname(name);
  725. X    if (hp == NULL)
  726. X    {
  727. X        return NOTOK;
  728. X    }
  729. X    memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
  730. X    return OK;
  731. }
  732. X
  733. X
  734. int Connection::connect()
  735. {
  736. X    if (::connect(sock, (struct sockaddr *)&server, sizeof(server)) == NOTOK)
  737. X    {
  738. X        return NOTOK;
  739. X    }
  740. X    return OK;
  741. }
  742. X
  743. X
  744. int Connection::bind()
  745. {
  746. X    if (::bind(sock, (struct sockaddr *)&server, sizeof(server)) == NOTOK)
  747. X    {
  748. X        return NOTOK;
  749. X    }
  750. X    return OK;
  751. }
  752. X
  753. X
  754. int Connection::get_port()
  755. {
  756. X    int    length;
  757. X
  758. X    if (getsockname(sock, (struct sockaddr *)&server, &length) == NOTOK)
  759. X    {
  760. X        return NOTOK;
  761. X    }
  762. X    return ntohs(server.sin_port);
  763. }
  764. X
  765. X
  766. int Connection::listen(int n)
  767. {
  768. X    return ::listen(sock, n);
  769. }
  770. X
  771. X
  772. Connection *Connection::accept(int priv)
  773. {
  774. X    int    newsock;
  775. X
  776. X    while (TRUE)
  777. X    {
  778. X        newsock = ::accept(sock, (struct sockaddr *)0, (int *)0);
  779. X        if (newsock == NOTOK && errno == EINTR)
  780. X            continue;
  781. X        break;
  782. X    }
  783. X    if (newsock == NOTOK)
  784. X        return (Connection *)0;
  785. X
  786. X    Connection    *newconnect = new Connection;
  787. X    newconnect->sock = newsock;
  788. X
  789. X    int length = sizeof(newconnect->server);
  790. X    getpeername(newsock, (struct sockaddr *)&newconnect->server, &length);
  791. X
  792. X    if (priv && newconnect->server.sin_port >= IPPORT_RESERVED)
  793. X    {
  794. X        delete newconnect;
  795. X        return (Connection *)0;
  796. X    }
  797. X
  798. X    return newconnect;
  799. }
  800. X
  801. X
  802. //*************************************************************************
  803. // Connection *Connection::accept_privileged()
  804. // PURPOSE:
  805. //   Accept  in  incoming  connection  but  only  if  it  is  from a
  806. //   privileged port
  807. //
  808. Connection * Connection::accept_privileged()
  809. {
  810. X    return accept(1);
  811. }
  812. X
  813. X
  814. //*************************************************************************
  815. // METHOD int Connection::write(char *buffer, int length)
  816. // PURPOSE:
  817. //   Write  <nbytes>  bytes  from  <buffer>  to file sock. This will
  818. //   take  care  of  problems where write will return without having
  819. //   written everything in the buffer.
  820. // PARAMETERS:
  821. //   char    *buffer:    The buffer to write.
  822. //   int    nbytes:        The number of bytes to write from <buffer>.
  823. // RETURN VALUE:
  824. //   Returns  number  of  bytes  actually  written.  If there was an
  825. //   error it returns -1.
  826. // SIDE EFFECTS:
  827. //   None
  828. // ASSUMPTIONS:
  829. //   None
  830. // FUNCTIONS USED:
  831. //   write()
  832. // ALGORYTHM:
  833. //   Stevens p. 279
  834. //
  835. int Connection::write(char *buffer, int length)
  836. {
  837. X    int    nleft, nwritten;
  838. X
  839. X    nleft = length;
  840. X    while (nleft > 0)
  841. X    {
  842. X        nwritten = ::write(sock, buffer, nleft);
  843. X        if (nwritten <= 0)
  844. X            return nwritten;
  845. X        nleft -= nwritten;
  846. X        buffer += nwritten;
  847. X    }
  848. X    return length - nleft;
  849. }
  850. X
  851. X
  852. //*************************************************************************
  853. // METHOD int Connection::write(char *buffer)
  854. // PURPOSE:
  855. //   This is identical to the other write except that the length of the
  856. //   buffer is not passed.  The buffer is assumed to be NULL terminated.
  857. // PARAMETERS:
  858. //   char    *buffer:    The buffer to write.
  859. // RETURN VALUE:
  860. //   Returns  number  of  bytes  actually  written.  If there was an
  861. //   error it returns -1.
  862. //
  863. int Connection::write(char *buffer)
  864. {
  865. X    return write(buffer, strlen(buffer));
  866. }
  867. X
  868. X
  869. //*************************************************************************
  870. // int Connection::read(char *buffer, int length)
  871. // PURPOSE:
  872. //   Read  <length>  bytes  from the current TCP connection. We will
  873. //   not  return  until  we  have  all  the  data we are waiting for
  874. //   unless there was an error
  875. // PARAMETERS:
  876. //   char *buffer:    Buffer to read the data into
  877. //   int length:    The number of bytes to read into the buffer
  878. // RETURN VALUE:
  879. //   The actual number of bytes read.  NOTOK if an error occured.
  880. // ASSUMPTIONS:
  881. //   The connection has been previously established.
  882. // FUNCTIONS USED:
  883. //   read()
  884. // ALGORYTHM:
  885. //   Stevens p. 279
  886. //
  887. int Connection::read(char *buffer, int length)
  888. {
  889. X    int    nleft, nread;
  890. X
  891. X    nleft = length;
  892. X    while (nleft > 0)
  893. X    {
  894. X        nread = ::read(sock, buffer, nleft);
  895. X        if (nread < 0 && errno == EINTR)
  896. X            continue;
  897. X        else if (nread < 0)
  898. X        {
  899. X            perror("read");
  900. X            return nread;
  901. X        }
  902. X        else if (nread == 0)
  903. X            return -1;            // End of file/stream
  904. X
  905. X        nleft -= nread;
  906. X        buffer += nread;
  907. X    }
  908. X    return length - nleft;
  909. }
  910. X
  911. X
  912. //***************************************************************************
  913. // char *Connection::read_line(char *buffer, int maxlength)
  914. // PURPOSE:
  915. //   Read a line of text, terminated by CR and or LF.
  916. //
  917. char *Connection::read_line(char *buffer, int maxlength)
  918. {
  919. X    while (maxlength > 0)
  920. X    {
  921. X        int    ch = get_char();
  922. X        if (ch < 0)
  923. X            return (char *) 0;
  924. X        else if (ch == '\r')
  925. X            continue;
  926. X        else if (ch == '\n')
  927. X            break;
  928. X        else
  929. X        {
  930. X            *buffer++ = ch;
  931. X            maxlength--;
  932. X        }
  933. X    }
  934. X    *buffer = '\0';
  935. X    return buffer;
  936. }
  937. X
  938. X
  939. //*************************************************************************
  940. // int Connection::read_partial(char *buffer, int maxlength)
  941. // PURPOSE:
  942. //   Read  at  most  <maxlength>  from  the  current TCP connection.
  943. //   This  is  equivalent  to  the  workings  of the standard read()
  944. //   system call
  945. // PARAMETERS:
  946. //   char *buffer:    Buffer to read the data into
  947. //   int maxlength:    Maximum number of bytes to read into the buffer
  948. // RETURN VALUE:
  949. //   The actual number of bytes read in.
  950. // ASSUMPTIONS:
  951. //   The connection has been previously established.
  952. // FUNCTIONS USED:
  953. //   read()
  954. //
  955. int Connection::read_partial(char *buffer, int maxlength)
  956. {
  957. X    return ::read(sock, buffer, maxlength);
  958. }
  959. X
  960. X
  961. //*************************************************************************
  962. // int Connection::bytes_available()
  963. // PURPOSE:
  964. //   Check  to  see  how  many bytes can be read from the connection
  965. //   currently
  966. // RETURN VALUE:
  967. //   The number of bytes available.
  968. //
  969. int Connection::bytes_available()
  970. {
  971. X    int    count = -1;
  972. X
  973. X    ioctl(sock, FIONREAD, (char *) &count);
  974. X
  975. X    return count;
  976. }
  977. X
  978. X
  979. //*************************************************************************
  980. // char * Connection::socket_as_string()
  981. // PURPOSE:
  982. //   Return  the  numeric  ASCII  equivalent  of  the socket number.
  983. //   This is needed to pass the socket to another program
  984. //
  985. char * Connection::socket_as_string()
  986. {
  987. X    char    buffer[20];
  988. X
  989. X    sprintf(buffer, "%d", sock);
  990. X    return strdup(buffer);
  991. }
  992. X
  993. X
  994. //*************************************************************************
  995. // int Connection::get_socket()
  996. // PURPOSE:
  997. //   Return the current socket number
  998. //
  999. int Connection::get_socket()
  1000. {
  1001. X    return sock;
  1002. }
  1003. X
  1004. X
  1005. //*************************************************************************
  1006. // int Connection::isopen()
  1007. // PURPOSE:
  1008. //   Return true if the connection is open
  1009. //
  1010. int Connection::isopen()
  1011. {
  1012. X    return sock >= 0;
  1013. }
  1014. X
  1015. X
  1016. //*************************************************************************
  1017. // int Connection::get_char()
  1018. //
  1019. int Connection::get_char()
  1020. {
  1021. X    if (pos >= pos_max)
  1022. X    {
  1023. X        pos_max = read_partial(buffer, BUFFER_SIZE);
  1024. X        pos = 0;
  1025. X        if (pos_max <= 0)
  1026. X            return -1;
  1027. X    }
  1028. X    return buffer[pos++];
  1029. }
  1030. X
  1031. X
  1032. SHAR_EOF
  1033. chmod 0644 Connection.cc ||
  1034. echo 'restore of Connection.cc failed'
  1035. Wc_c="`wc -c < 'Connection.cc'`"
  1036. test 8558 -eq "$Wc_c" ||
  1037.     echo 'Connection.cc: original size 8558, current size' "$Wc_c"
  1038. fi
  1039. # ============= GWAbout.cc ==============
  1040. if test -f 'GWAbout.cc' -a X"$1" != X"-c"; then
  1041.     echo 'x - skipping GWAbout.cc (File already exists)'
  1042. else
  1043. echo 'x - extracting GWAbout.cc (Text)'
  1044. sed 's/^X//' << 'SHAR_EOF' > 'GWAbout.cc' &&
  1045. //
  1046. // GWAbout.cc
  1047. //
  1048. // (c) Copyright 1993, San Diego State University -- College of Sciences
  1049. //       (See the COPYRIGHT file for more Copyright information)
  1050. //
  1051. // Implementation of the GWAbout class
  1052. //
  1053. #include "GWAbout.h"
  1054. #include "xvgopher.h"
  1055. #include "cursor.h"
  1056. #include <fcntl.h>
  1057. #include <unistd.h>
  1058. X
  1059. #define    KEY_TEXT_ITEM        20000
  1060. X
  1061. X
  1062. static int            current_icon = 0;
  1063. static Panel_item    icon;
  1064. X
  1065. X
  1066. //***************************************************************************
  1067. // GWAbout::GWAbout(Frame par)
  1068. //
  1069. GWAbout::GWAbout(Frame par)
  1070. {
  1071. X    parent = par;
  1072. }
  1073. X
  1074. X
  1075. //***************************************************************************
  1076. // int GWAbout::open(Response *)
  1077. // PURPOSE:
  1078. //   This will create an about window
  1079. //
  1080. int GWAbout::open(Response *)
  1081. {
  1082. X    info = NULL;
  1083. X    compute_location(407, 107);
  1084. X    frame = (Frame) xv_create(parent, FRAME_CMD,
  1085. X        XV_X,                            next_x,
  1086. X        XV_Y,                            next_y,
  1087. X        XV_WIDTH,                        465,
  1088. X        XV_HEIGHT,                        369,
  1089. X        FRAME_LABEL,                    "About XvGopher",
  1090. X        FRAME_CMD_PIN_STATE,            FRAME_CMD_PIN_OUT,
  1091. X        FRAME_SHOW_RESIZE_CORNER,        FALSE,
  1092. X        XV_SHOW,                        TRUE,
  1093. X        FRAME_SHOW_FOOTER,                FALSE,
  1094. X        FRAME_DONE_PROC,                (void (*)(Frame)) done_proc,
  1095. X        XV_KEY_DATA,                    KEY_GWINDOW,    this,
  1096. X        NULL);
  1097. X    panel = (Panel) xv_get(frame, FRAME_CMD_PANEL);
  1098. X
  1099. X    //
  1100. X    // Interpose onto the panel so that events will generate a call
  1101. X    //
  1102. X    notify_interpose_event_func(panel, (Notify_func) panel_events, NOTIFY_SAFE);
  1103. X
  1104. X    //
  1105. X    // Create all the panel items
  1106. X    //
  1107. X    icon = (Panel_item) xv_create(panel, PANEL_MESSAGE,
  1108. X        XV_X,                            24,
  1109. X        XV_Y,                            12,
  1110. X        PANEL_LABEL_IMAGE,                get_gopher(0),
  1111. X        NULL);
  1112. X    xv_create(panel, PANEL_MESSAGE,
  1113. X        XV_X,                            112,
  1114. X        XV_Y,                            16,
  1115. X        PANEL_LABEL_STRING,                "XvGopher",
  1116. X        PANEL_LABEL_BOLD,                TRUE,
  1117. X        NULL);
  1118. X    xv_create(panel, PANEL_MESSAGE,
  1119. X        XV_X,                            112,
  1120. X        XV_Y,                            39,
  1121. X        PANEL_LABEL_STRING,                "Version 1.0",
  1122. X        PANEL_LABEL_BOLD,                TRUE,
  1123. X        NULL);
  1124. X    xv_create(panel, PANEL_MESSAGE,
  1125. X        XV_X,                            112,
  1126. X        XV_Y,                            62,
  1127. X        PANEL_LABEL_STRING,                "(c) Copyright 1993, San Diego StateUniversity",
  1128. X        PANEL_LABEL_BOLD,                TRUE,
  1129. X        NULL);
  1130. X    xv_create(panel, PANEL_MESSAGE,
  1131. X        XV_X,                            20,
  1132. X        XV_Y,                            96,
  1133. X        PANEL_LABEL_STRING,                "XvGopher was written in C++ by Andrew Scherpbier at SDSU.",
  1134. X        PANEL_LABEL_BOLD,                FALSE,
  1135. X        NULL);
  1136. X    xv_create(panel, PANEL_MESSAGE,
  1137. X        XV_X,                            20,
  1138. X        XV_Y,                            124,
  1139. X        PANEL_LABEL_STRING,                "Many thanks to the following people for testing, suggestions, and beer:",
  1140. X        PANEL_LABEL_BOLD,                FALSE,
  1141. X        NULL);
  1142. X    xv_create(panel, PANEL_MESSAGE,
  1143. X        XV_X,                            56,
  1144. X        XV_Y,                            156,
  1145. X        PANEL_LABEL_STRING,                "Mark Boyns",
  1146. X        PANEL_LABEL_BOLD,                TRUE,
  1147. X        NULL);
  1148. X    xv_create(panel, PANEL_MESSAGE,
  1149. X        XV_X,                            56,
  1150. X        XV_Y,                            179,
  1151. X        PANEL_LABEL_STRING,                "John Denune",
  1152. X        PANEL_LABEL_BOLD,                TRUE,
  1153. X        NULL);
  1154. X    xv_create(panel, PANEL_MESSAGE,
  1155. X        XV_X,                            56,
  1156. X        XV_Y,                            202,
  1157. X        PANEL_LABEL_STRING,                "Mike Halderman",
  1158. X        PANEL_LABEL_BOLD,                TRUE,
  1159. X        NULL);
  1160. X    xv_create(panel, PANEL_MESSAGE,
  1161. X        XV_X,                            56,
  1162. X        XV_Y,                            225,
  1163. X        PANEL_LABEL_STRING,                "Paul Lindner",
  1164. X        PANEL_LABEL_BOLD,                TRUE,
  1165. X        NULL);
  1166. X    xv_create(panel, PANEL_MESSAGE,
  1167. X        XV_X,                            216,
  1168. X        XV_Y,                            156,
  1169. X        PANEL_LABEL_STRING,                "Layout, icons, gopher chew, testing",
  1170. X        PANEL_LABEL_BOLD,                FALSE,
  1171. X        NULL);
  1172. X    xv_create(panel, PANEL_MESSAGE,
  1173. X        XV_X,                            216,
  1174. X        XV_Y,                            179,
  1175. X        PANEL_LABEL_STRING,                "Testing",
  1176. X        PANEL_LABEL_BOLD,                FALSE,
  1177. X        NULL);
  1178. X    xv_create(panel, PANEL_MESSAGE,
  1179. X        XV_X,                            216,
  1180. X        XV_Y,                            202,
  1181. X        PANEL_LABEL_STRING,                "Testing",
  1182. X        PANEL_LABEL_BOLD,                FALSE,
  1183. X        NULL);
  1184. X    xv_create(panel, PANEL_MESSAGE,
  1185. X        XV_X,                            216,
  1186. X        XV_Y,                            225,
  1187. X        PANEL_LABEL_STRING,                "Gopher icon",
  1188. X        PANEL_LABEL_BOLD,                FALSE,
  1189. X        NULL);
  1190. X    xv_create(panel, PANEL_MESSAGE,
  1191. X        XV_X,                            20,
  1192. X        XV_Y,                            260,
  1193. X        PANEL_LABEL_STRING,                "If you have comments or suggestions, please send E-Mail to:",
  1194. X        PANEL_LABEL_BOLD,                FALSE,
  1195. X        NULL);
  1196. X    xv_create(panel, PANEL_MESSAGE,
  1197. X        XV_X,                            60,
  1198. X        XV_Y,                            292,
  1199. X        PANEL_LABEL_STRING,                "xvgopher@gopher.sdsu.edu",
  1200. X        PANEL_LABEL_BOLD,                TRUE,
  1201. X        NULL);
  1202. X    xv_create(panel, PANEL_BUTTON,
  1203. X        XV_X,                            201,
  1204. X        XV_Y,                            328,
  1205. X        PANEL_LABEL_STRING,                "Dismiss",
  1206. X        PANEL_NOTIFY_PROC,                dismiss_proc,
  1207. X        NULL);
  1208. X    return OK;
  1209. }
  1210. X
  1211. X
  1212. //***************************************************************************
  1213. // void GWAbout::dismiss_proc(Frame frame, Event *)
  1214. // PURPOS:
  1215. //   This gets called when the user presses 'q' in a window.
  1216. //
  1217. void GWAbout::dismiss_proc(Frame frame, Event *)
  1218. {
  1219. X    GWindow    *win = (GWindow *) xv_get(frame, XV_KEY_DATA, KEY_GWINDOW);
  1220. X    delete win;
  1221. X    xv_destroy_safe(frame);
  1222. }
  1223. X
  1224. X
  1225. //***************************************************************************
  1226. // void GWAbout::done_proc(Frame frame)
  1227. // PURPOSE:
  1228. //   This gets called whenever the about window is destroyed.  We need to
  1229. //   clean up the associated GWindow structure.  Since we want all children
  1230. //   to go away as well, we will call this function recursively on our subframes.
  1231. //
  1232. void GWAbout::done_proc(Frame frame)
  1233. {
  1234. X    if (!frame)
  1235. X        return;
  1236. X    GWindow    *win = (GWindow *) xv_get(frame, XV_KEY_DATA, KEY_GWINDOW);
  1237. X    delete win;
  1238. X    xv_destroy_safe(frame);
  1239. }
  1240. X
  1241. X
  1242. //***************************************************************************
  1243. // void GWAbout::panel_events(Xv_window, Event *, Notify_arg, Notify_event_type)
  1244. //
  1245. Notify_value GWAbout::panel_events(Xv_window win, Event *event, Notify_arg arg, Notify_event_type type)
  1246. {
  1247. X    current_icon ^= 1;
  1248. X    xv_set(icon,
  1249. X        PANEL_LABEL_IMAGE,                get_gopher(current_icon),
  1250. X        NULL);
  1251. X    return notify_next_event_func(win, (Notify_event) event, arg, type);
  1252. }
  1253. X
  1254. SHAR_EOF
  1255. chmod 0664 GWAbout.cc ||
  1256. echo 'restore of GWAbout.cc failed'
  1257. Wc_c="`wc -c < 'GWAbout.cc'`"
  1258. test 5530 -eq "$Wc_c" ||
  1259.     echo 'GWAbout.cc: original size 5530, current size' "$Wc_c"
  1260. fi
  1261. # ============= GWBinary.cc ==============
  1262. if test -f 'GWBinary.cc' -a X"$1" != X"-c"; then
  1263.     echo 'x - skipping GWBinary.cc (File already exists)'
  1264. else
  1265. echo 'x - extracting GWBinary.cc (Text)'
  1266. sed 's/^X//' << 'SHAR_EOF' > 'GWBinary.cc' &&
  1267. //
  1268. // GWBinary.cc
  1269. //
  1270. // (c) Copyright 1993, San Diego State University -- College of Sciences
  1271. //       (See the COPYRIGHT file for more Copyright information)
  1272. //
  1273. // Implementation of the GWBinary class
  1274. //
  1275. #include "GWBinary.h"
  1276. #include "xvgopher.h"
  1277. #include "cursor.h"
  1278. #include <fcntl.h>
  1279. #include <unistd.h>
  1280. X
  1281. X
  1282. //***************************************************************************
  1283. // GWBinary::GWBinary(Frame par)
  1284. //
  1285. GWBinary::GWBinary(Frame par) : GWDownload(par, GWDownload::BINARY)
  1286. {
  1287. }
  1288. X
  1289. X
  1290. SHAR_EOF
  1291. chmod 0644 GWBinary.cc ||
  1292. echo 'restore of GWBinary.cc failed'
  1293. Wc_c="`wc -c < 'GWBinary.cc'`"
  1294. test 498 -eq "$Wc_c" ||
  1295.     echo 'GWBinary.cc: original size 498, current size' "$Wc_c"
  1296. fi
  1297. # ============= GWBookmarks.cc ==============
  1298. if test -f 'GWBookmarks.cc' -a X"$1" != X"-c"; then
  1299.     echo 'x - skipping GWBookmarks.cc (File already exists)'
  1300. else
  1301. echo 'x - extracting GWBookmarks.cc (Text)'
  1302. sed 's/^X//' << 'SHAR_EOF' > 'GWBookmarks.cc' &&
  1303. //
  1304. // GWBookmarks.cc
  1305. //
  1306. // (c) Copyright 1993, San Diego State University -- College of Sciences
  1307. //       (See the COPYRIGHT file for more Copyright information)
  1308. //
  1309. //   This  file  contains  the  routines  of the GWBookmarks class which
  1310. //   deal with the opening of windows.
  1311. //
  1312. #include "GWBookmarks.h"
  1313. #include "xvgopher.h"
  1314. #include "cursor.h"
  1315. #include "icons.h"
  1316. #include <fstream.h>
  1317. #include <string.h>
  1318. #include <xview/svrimage.h>
  1319. #include <xview/icon.h>
  1320. #include <xview/defaults.h>
  1321. X
  1322. X
  1323. #define    KEY_SAVE_BTN        30010
  1324. #define    KEY_SAVE_TXT        30011
  1325. X
  1326. X
  1327. GWBookmarks    *bookmarks;
  1328. X
  1329. X
  1330. //***************************************************************************
  1331. // GWBookmarks::GWBookmarks(Frame par)
  1332. //
  1333. GWBookmarks::GWBookmarks(Frame par)
  1334. {
  1335. X    parent = par;
  1336. }
  1337. X
  1338. X
  1339. //***************************************************************************
  1340. // GWBookmarks::~GWBookmarks()
  1341. //
  1342. GWBookmarks::~GWBookmarks()
  1343. {
  1344. X    write_bookmarks();
  1345. }
  1346. X
  1347. X
  1348. //***************************************************************************
  1349. // int GWBookmarks::open(Response *resp)
  1350. // PURPOSE:
  1351. //   This  will  create a window in which the bookmarks directory will be
  1352. //   displayed.
  1353. //
  1354. int GWBookmarks::open(Response *resp)
  1355. {
  1356. X    if (GWList::open(resp) != OK)
  1357. X        return NOTOK;
  1358. X
  1359. X    int    left = 8;        // Position of leftmost button in window
  1360. X    
  1361. X    //
  1362. X    // Create the save button and save text field.
  1363. X    //
  1364. X    Panel_item save_btn = (Panel_item) xv_create(panel, PANEL_BUTTON,
  1365. X        XV_X,                            left,
  1366. X        XV_Y,                            8,
  1367. X        PANEL_LABEL_STRING,                "Save",
  1368. X        PANEL_INACTIVE,                    TRUE,
  1369. X        NULL);
  1370. X    Panel_item save_txt = (Panel_item) xv_create(panel, PANEL_TEXT,
  1371. X        XV_X,                            left + 56,
  1372. X        XV_Y,                            8,
  1373. X        PANEL_LABEL_STRING,                "Save in:",
  1374. X        PANEL_VALUE_DISPLAY_WIDTH,        260,
  1375. X        PANEL_INACTIVE,                    TRUE,
  1376. X        NULL);
  1377. X
  1378. X    xv_set(dir_list,
  1379. X        XV_KEY_DATA,                    KEY_SAVE_BTN,    save_btn,
  1380. X        XV_KEY_DATA,                    KEY_SAVE_TXT,    save_txt,
  1381. X        NULL);
  1382. X
  1383. X    //
  1384. X    //   Now  some  things  which  need  to  be  set for both FRAMEs and
  1385. X    //   FRAME_CMDs
  1386. X    //
  1387. X    xv_set(frame,
  1388. X        FRAME_SHOW_FOOTER,                TRUE,
  1389. X        FRAME_RIGHT_FOOTER,                "Local bookmarks",
  1390. X        FRAME_DONE_PROC,                (void (*)(Frame)) done_proc,
  1391. X        XV_KEY_DATA,                    KEY_GWINDOW,    this,
  1392. X        XV_SHOW,                        preferences.get_popup_bookmarks(),
  1393. X        FRAME_LABEL,                    "Xvgopher Bookmarks",
  1394. X        NULL);
  1395. X
  1396. X    modify_list_menu();
  1397. X
  1398. X    read_bookmarks();
  1399. X
  1400. X    return OK;
  1401. }
  1402. X
  1403. X
  1404. //***************************************************************************
  1405. // void GWBookmarks::read_bookmarks()
  1406. //
  1407. void GWBookmarks::read_bookmarks()
  1408. {
  1409. X    char        *home = getenv("HOME");
  1410. X    if (!home)
  1411. X        home = ".";
  1412. X    char        filename[100];
  1413. X    sprintf(filename, "%s/.xvgopher-bm", home);
  1414. X    ifstream    in(filename);
  1415. X    if (in.fail())
  1416. X        return;
  1417. X
  1418. X    xv_set(dir_list,
  1419. X        XV_SHOW,                    FALSE,
  1420. X        NULL);
  1421. X    char    buffer[10000];
  1422. X    int        i = 0;
  1423. X    while (!in.eof())
  1424. X    {
  1425. X        in.getline(buffer, 10000);
  1426. X        if (in.eof())
  1427. X            break;
  1428. X        if (i == 0)    // First line of the file
  1429. X        {
  1430. X            //
  1431. X            // The first line of the file is supposed to contain the version number.
  1432. X            // However, if the file does not contain one, we will just assume that
  1433. X            // the file was created with version 1.0
  1434. X            //
  1435. X            if (strncmp(buffer, "XvGo", 4) == 0)
  1436. X            {
  1437. X                //
  1438. X                // We got a version number!
  1439. X                //
  1440. X                continue;    // There is only one version, so what are we worrying about???
  1441. X            }
  1442. X        }
  1443. X        Response    *r = new Response(buffer);
  1444. X        xv_set(dir_list,
  1445. X            PANEL_LIST_INSERT,            i,
  1446. X            PANEL_LIST_STRING,            i, r->get_title(),
  1447. X            PANEL_LIST_GLYPH,            i, get_image(r->get_type()),
  1448. X            PANEL_LIST_CLIENT_DATA,        i, r,
  1449. X            NULL);
  1450. X        i++;
  1451. X    }
  1452. X    xv_set(dir_list,
  1453. X        XV_SHOW,                    TRUE,
  1454. X        NULL);
  1455. }
  1456. X
  1457. X
  1458. //***************************************************************************
  1459. // void GWBookmarks::write_bookmarks()
  1460. //
  1461. void GWBookmarks::write_bookmarks()
  1462. {
  1463. X    char        *home = getenv("HOME");
  1464. X    if (!home)
  1465. X        home = ".";
  1466. X    char        filename[100];
  1467. X    sprintf(filename, "%s/.xvgopher-bm", home);
  1468. X    ofstream    out(filename);
  1469. X    if (out.fail())
  1470. X        return;
  1471. X
  1472. X    int        n = (int) xv_get(dir_list, PANEL_LIST_NROWS);
  1473. X
  1474. X    //
  1475. X    // First put the version number in the file so that we can determine later on
  1476. X    // if the file needs conversion or not.
  1477. X    //
  1478. X    out << "XvGo " << VERSION << "\n";
  1479. X
  1480. X    for (int i = 0; i < n; i++)
  1481. X    {
  1482. X        Response    *r = (Response *) xv_get(dir_list, PANEL_LIST_CLIENT_DATA, i);
  1483. X        out << r->get_type() << r->get_title() << "\t" << r->get_command() << "\t" <<
  1484. X                r->get_server() << "\t" << r->get_port() << "\n";
  1485. X    }
  1486. X    out.close();
  1487. }
  1488. X
  1489. X
  1490. //***************************************************************************
  1491. // void GWBookmarks::row_deselect(int row, Response *resp)
  1492. //
  1493. void GWBookmarks::row_deselect(int row, Response *resp)
  1494. {
  1495. X    Panel_item        save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
  1496. X    Panel_item        save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);
  1497. X
  1498. X    row = row;
  1499. X    resp = resp;
  1500. X    //
  1501. X    // Hide the button and the text item
  1502. X    //
  1503. X    xv_set(save_btn,
  1504. X        PANEL_INACTIVE,        TRUE,
  1505. X        NULL);
  1506. X    xv_set(save_txt,
  1507. X        PANEL_INACTIVE,        TRUE,
  1508. X        NULL);
  1509. X
  1510. X    //
  1511. X    // The menu of the dir_list has the remove item.  This needs to be made inactive.
  1512. X    //
  1513. X    xv_set(bookmark_mi,
  1514. X        MENU_INACTIVE,                    TRUE,
  1515. X        NULL);
  1516. X    xv_set(show_info_mi,
  1517. X        MENU_INACTIVE,                    TRUE,
  1518. X        NULL);
  1519. }
  1520. X
  1521. X
  1522. //***************************************************************************
  1523. // void GWBookmarks::row_select(int row, Response *resp)
  1524. //
  1525. void GWBookmarks::row_select(int row, Response *resp)
  1526. {
  1527. X    Panel_item        save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
  1528. X    Panel_item        save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);
  1529. X
  1530. X    row = row;
  1531. X    resp = resp;
  1532. X    //
  1533. X    // Show the button and the text item if the selected item is savable
  1534. X    //
  1535. X    if (strchr("09", resp->get_type()))
  1536. X    {
  1537. X        xv_set(save_btn,
  1538. X            PANEL_INACTIVE,        FALSE,
  1539. X            NULL);
  1540. X        xv_set(save_txt,
  1541. X            PANEL_INACTIVE,        FALSE,
  1542. X            NULL);
  1543. X    }
  1544. X
  1545. X    //
  1546. X    // The menu of the dir_list has the remove item.  This needs to be made active.
  1547. X    //
  1548. X    xv_set(bookmark_mi,
  1549. X        MENU_INACTIVE,                    FALSE,
  1550. X        NULL);
  1551. X    xv_set(show_info_mi,
  1552. X        MENU_INACTIVE,                    FALSE,
  1553. X        NULL);
  1554. }
  1555. X
  1556. X
  1557. //***************************************************************************
  1558. // void GWBookmarks::show()
  1559. //
  1560. void GWBookmarks::show()
  1561. {
  1562. X    xv_set(frame,
  1563. X        XV_SHOW,                TRUE,
  1564. X        NULL);
  1565. }
  1566. X
  1567. X
  1568. //***************************************************************************
  1569. // void GWBookmarks::add(Response *resp)
  1570. // PURPOSE:
  1571. //   Add a line to the list of bookmarks.
  1572. //
  1573. void GWBookmarks::add(Response *resp)
  1574. {
  1575. X    xv_set(dir_list,
  1576. X        XV_SHOW,                    FALSE,
  1577. X        NULL);
  1578. X
  1579. X    int    n = (int) xv_get(dir_list, PANEL_LIST_NROWS);
  1580. X    xv_set(dir_list,
  1581. X        PANEL_LIST_INSERT,            n,
  1582. X        PANEL_LIST_STRING,            n, resp->get_title(),
  1583. X        PANEL_LIST_GLYPH,            n, get_image(resp->get_type()),
  1584. X        PANEL_LIST_CLIENT_DATA,        n, resp,
  1585. X        NULL);
  1586. X
  1587. X    xv_set(dir_list,
  1588. X        XV_SHOW,                    TRUE,
  1589. X        NULL);
  1590. }
  1591. X
  1592. X
  1593. //***************************************************************************
  1594. // void GWBookmarks::modify_list_menu()
  1595. //   Modify the Bookmarks List menu so that if contains the following items:
  1596. //        Remove bookmark
  1597. //        Show item info
  1598. //
  1599. void GWBookmarks::modify_list_menu()
  1600. {
  1601. X    //
  1602. X    // We want to modify the scrolling list's menu, so we need to get it,
  1603. X    // add the items and then put it back.
  1604. X    //
  1605. X    Menu    m = (Menu) xv_get(dir_list, PANEL_ITEM_MENU);
  1606. X    bookmark_mi = (Menu_item) xv_create(NULL, MENUITEM,
  1607. X        MENU_STRING,                    "Remove bookmark",
  1608. X        MENU_NOTIFY_PROC,                remove_bookmark_proc,
  1609. X        MENU_INACTIVE,                    TRUE,
  1610. X        XV_KEY_DATA,                    KEY_GWINDOW, this,
  1611. X        NULL);
  1612. X    xv_set(m,
  1613. X        MENU_APPEND_ITEM,                bookmark_mi,
  1614. X        NULL);
  1615. X    show_info_mi = (Menu_item) xv_create(NULL, MENUITEM,
  1616. X        MENU_STRING,                    "Show item info",
  1617. X        MENU_NOTIFY_PROC,                show_item_info_proc,
  1618. X        MENU_INACTIVE,                    FALSE,
  1619. X        XV_KEY_DATA,                    KEY_GWINDOW, this,
  1620. X        NULL);
  1621. X    xv_set(m,
  1622. X        MENU_APPEND_ITEM,                show_info_mi,
  1623. X        NULL);
  1624. X    xv_set(dir_list,
  1625. X        PANEL_ITEM_MENU,                m,
  1626. X        NULL);
  1627. }
  1628. X
  1629. X
  1630. //***************************************************************************
  1631. // void GWBookmarks::remove_bookmark_proc(Menu menu, Menu_item mi)
  1632. //
  1633. void GWBookmarks::remove_bookmark_proc(Menu menu, Menu_item mi)
  1634. {
  1635. X    GWBookmarks        *gwindow = (GWBookmarks *) xv_get(mi, XV_KEY_DATA, KEY_GWINDOW);
  1636. X
  1637. X    //
  1638. X    // First make sure that there really is a row selected...
  1639. X    //
  1640. X    if (!xv_get(gwindow->dir_list, PANEL_LIST_SELECTED, gwindow->current_selected))
  1641. X        return;
  1642. X
  1643. X    menu = menu;
  1644. X    //
  1645. X    // Some row was selected and we need to remove the row from the list.
  1646. X    //
  1647. X    Response *r = (Response *) xv_get(gwindow->dir_list, PANEL_LIST_CLIENT_DATA, gwindow->current_selected);
  1648. X    delete r;
  1649. X    xv_set(gwindow->dir_list,
  1650. X        PANEL_LIST_DELETE,            gwindow->current_selected,
  1651. X        NULL);
  1652. X    xv_set(gwindow->bookmark_mi,
  1653. X        MENU_INACTIVE,                    TRUE,
  1654. X        NULL);
  1655. }
  1656. X
  1657. X
  1658. //***************************************************************************
  1659. // void GWBookmarks::done_proc(Frame frame)
  1660. //   This gets called whenever a command frame is destroyed.  In the case
  1661. //   of the book marks window, we only need to hide the window.
  1662. //
  1663. void GWBookmarks::done_proc(Frame frame)
  1664. {
  1665. X    xv_set(frame,
  1666. X        XV_SHOW,                FALSE,
  1667. X        NULL);
  1668. }
  1669. X
  1670. X
  1671. //***************************************************************************
  1672. SHAR_EOF
  1673. chmod 0664 GWBookmarks.cc ||
  1674. echo 'restore of GWBookmarks.cc failed'
  1675. Wc_c="`wc -c < 'GWBookmarks.cc'`"
  1676. test 8907 -eq "$Wc_c" ||
  1677.     echo 'GWBookmarks.cc: original size 8907, current size' "$Wc_c"
  1678. fi
  1679. # ============= GWDirectory.cc ==============
  1680. if test -f 'GWDirectory.cc' -a X"$1" != X"-c"; then
  1681.     echo 'x - skipping GWDirectory.cc (File already exists)'
  1682. else
  1683. echo 'x - extracting GWDirectory.cc (Text)'
  1684. sed 's/^X//' << 'SHAR_EOF' > 'GWDirectory.cc' &&
  1685. //
  1686. // GWDirectory.cc
  1687. //
  1688. // (c) Copyright 1993, San Diego State University -- College of Sciences
  1689. //       (See the COPYRIGHT file for more Copyright information)
  1690. //
  1691. //   This  file  contains  the  routines  of the GWDirectory class which
  1692. //   deal with the opening of windows.
  1693. //
  1694. #include "GWDirectory.h"
  1695. #include "xvgopher.h"
  1696. #include "GWBookmarks.h"
  1697. #include "GWPref.h"
  1698. #include "GWAbout.h"
  1699. #include "GWGopher.h"
  1700. #include <xview/notice.h>
  1701. #include <stream.h>
  1702. #include <string.h>
  1703. X
  1704. X
  1705. #define    KEY_SAVE_BTN        30010
  1706. #define    KEY_SAVE_TXT        30011
  1707. X
  1708. X
  1709. //***************************************************************************
  1710. // GWDirectory::GWDirectory(Frame par)
  1711. //
  1712. GWDirectory::GWDirectory(Frame par)
  1713. {
  1714. X    parent = par;
  1715. }
  1716. X
  1717. X
  1718. //***************************************************************************
  1719. // int GWDirectory::open(Response *resp)
  1720. // PURPOSE:
  1721. //   This  will  create a window in which a gopher directory will be
  1722. //   displayed.  There  is a special case for this window: it can be
  1723. //   the  first  window  created  for  this  program.  Hence, if the
  1724. //   parent  is  NULL, the window will NOT be a command window but a
  1725. //   regular window.
  1726. //
  1727. int GWDirectory::open(Response *resp)
  1728. {
  1729. X    //
  1730. X    // Let the base class create the window.  We will only add the buttons
  1731. X    //
  1732. X    if (GWList::open(resp) != OK)
  1733. X        return NOTOK;
  1734. X
  1735. X    int    left = 8;        // Position of leftmost button in window
  1736. X    if (!parent)
  1737. X    {
  1738. X        //
  1739. X        //   The main frame gets the Gopher menu button and the Quit
  1740. X        //   button
  1741. X        //
  1742. X        Menu menu = (Menu) xv_create(NULL, MENU,
  1743. X            MENU_NOTIFY_PROC,                menu_proc,
  1744. X            MENU_ITEM,
  1745. X                MENU_STRING,                "Bookmarks...",
  1746. X                NULL,
  1747. X            MENU_ITEM,
  1748. X                MENU_STRING,                "Another Gopher...",
  1749. X                NULL,
  1750. X            MENU_ITEM,
  1751. X                MENU_STRING,                "",
  1752. X                MENU_FEEDBACK,                FALSE,
  1753. X                NULL,
  1754. X            MENU_ITEM,
  1755. X                MENU_STRING,                "Preferences...",
  1756. X                NULL,
  1757. X            MENU_ITEM,
  1758. X                MENU_STRING,                "",
  1759. X                MENU_FEEDBACK,                FALSE,
  1760. X                NULL,
  1761. X            MENU_ITEM,
  1762. X                MENU_STRING,                "About...",
  1763. X                NULL,
  1764. X            XV_KEY_DATA,                    KEY_GWINDOW,    this,
  1765. X            NULL);
  1766. X        xv_create(panel, PANEL_BUTTON,
  1767. X            XV_X,                            8,
  1768. X            XV_Y,                            8,
  1769. X            PANEL_LABEL_STRING,                "Gopher",
  1770. X            PANEL_ITEM_MENU,                menu,
  1771. X            NULL);
  1772. X
  1773. X        //
  1774. X        //   Since  we  still  want  to put the other buttons in this panel,
  1775. X        //   we  need  to  make  sure  they  do  not overlap. That's why the
  1776. X        //   variable 'left' has the pixel location of the next button.
  1777. X        //
  1778. X        left = 92;
  1779. X
  1780. X        //
  1781. X        // Since we are the parent of all windows, there is only one of us.  Therefore,
  1782. X        // this is a good place to create the book marks window.
  1783. X        // The Response parameter to the open member is really a dummy.
  1784. X        //
  1785. X        bookmarks = new GWBookmarks(frame);
  1786. X        bookmarks->open(resp);
  1787. X
  1788. X        //
  1789. X        // The same holds true for the preferences window...
  1790. X        //
  1791. X        gwpref = new GWPref(frame);
  1792. X        gwpref->open(resp);
  1793. X    }
  1794. X
  1795. #if        USE_SAVE
  1796. X    //
  1797. X    // Create the save button and save text field.
  1798. X    //
  1799. X    Panel_item save_btn = (Panel_item) xv_create(panel, PANEL_BUTTON,
  1800. X        XV_X,                            left,
  1801. X        XV_Y,                            8,
  1802. X        PANEL_LABEL_STRING,                "Save",
  1803. X        PANEL_INACTIVE,                    TRUE,
  1804. X        NULL);
  1805. X    Panel_item save_txt = (Panel_item) xv_create(panel, PANEL_TEXT,
  1806. X        XV_X,                            left + 56,
  1807. X        XV_Y,                            8,
  1808. X        PANEL_LABEL_STRING,                "Save in:",
  1809. X        PANEL_VALUE_DISPLAY_WIDTH,        260,
  1810. X        PANEL_INACTIVE,                    TRUE,
  1811. X        NULL);
  1812. X
  1813. X    xv_set(dir_list,
  1814. X        XV_KEY_DATA,                    KEY_SAVE_BTN,    save_btn,
  1815. X        XV_KEY_DATA,                    KEY_SAVE_TXT,    save_txt,
  1816. X        NULL);
  1817. #endif    USE_SAVE
  1818. X
  1819. X    //
  1820. X    //   Now  some  things  which  need  to  be  set for both FRAMEs and
  1821. X    //   FRAME_CMDs
  1822. X    //
  1823. X    xv_set(frame,
  1824. X        XV_SHOW,                        TRUE,
  1825. X        FRAME_RIGHT_FOOTER,                info->get_server(),
  1826. X        FRAME_DONE_PROC,                done_proc,
  1827. X        NULL);
  1828. X
  1829. X    //
  1830. X    // Modify the list menu
  1831. X    //
  1832. X    modify_list_menu();
  1833. X
  1834. X    //
  1835. X    //   Let the user know that we are working on something...
  1836. X    //
  1837. X    frame_busy(frame);
  1838. X
  1839. X    //
  1840. X    //   Now we need to build the connection and get information from it
  1841. X    //
  1842. X    gopher = new Gopher(this);
  1843. X    if (gopher->open(info->get_server(), info->get_port()) == NOTOK)        // Connection
  1844. X    {
  1845. X        xv_create(frame, NOTICE,
  1846. X            NOTICE_MESSAGE_STRINGS,        "Unable to connect to remote gopher",
  1847. X                                        info->get_server(),
  1848. X                                        NULL,
  1849. X            NOTICE_BUTTON_YES,            "Bummer",
  1850. X            NOTICE_BLOCK_THREAD,        TRUE,
  1851. X            NOTICE_LOCK_SCREEN,            TRUE,
  1852. X            XV_SHOW,                    TRUE,
  1853. X            NULL);
  1854. X        return NOTOK;
  1855. X    }
  1856. X    gopher->read(info->get_type(), info->get_command());                    // Get info
  1857. X
  1858. X    return OK;
  1859. }
  1860. X
  1861. X
  1862. //***************************************************************************
  1863. // void GWDirectory::modify_list_menu()
  1864. //   Modify the Directory List menu so that if contains the following items:
  1865. //        Set bookmark
  1866. //        Show item info
  1867. //
  1868. void GWDirectory::modify_list_menu()
  1869. {
  1870. X    //
  1871. X    // We want to modify the scrolling list's menu, so we need to get it,
  1872. X    // add the items and then put it back.
  1873. X    //
  1874. X    Menu    m = (Menu) xv_get(dir_list, PANEL_ITEM_MENU);
  1875. X    bookmark_mi = (Menu_item) xv_create(NULL, MENUITEM,
  1876. X        MENU_STRING,                    "Set bookmark",
  1877. X        MENU_NOTIFY_PROC,                set_bookmark_proc,
  1878. X        MENU_INACTIVE,                    TRUE,
  1879. X        XV_KEY_DATA,                    KEY_GWINDOW, this,
  1880. X        NULL);
  1881. X    xv_set(m,
  1882. X        MENU_APPEND_ITEM,                bookmark_mi,
  1883. X        NULL);
  1884. X    show_info_mi = (Menu_item) xv_create(NULL, MENUITEM,
  1885. X        MENU_STRING,                    "Show item info",
  1886. X        MENU_NOTIFY_PROC,                show_item_info_proc,
  1887. X        MENU_INACTIVE,                    TRUE,
  1888. X        XV_KEY_DATA,                    KEY_GWINDOW, this,
  1889. X        NULL);
  1890. X    xv_set(m,
  1891. X        MENU_APPEND_ITEM,                show_info_mi,
  1892. X        NULL);
  1893. X    xv_set(dir_list,
  1894. X        PANEL_ITEM_MENU,                m,
  1895. X        NULL);
  1896. }
  1897. X
  1898. X
  1899. //***************************************************************************
  1900. // void GWDirectory::row_deselect(int, Response *)
  1901. //
  1902. void GWDirectory::row_deselect(int, Response *)
  1903. {
  1904. #if        USE_SAVE
  1905. X    //
  1906. X    // Hide the button and the text item
  1907. X    //
  1908. X    Panel_item        save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
  1909. X    Panel_item        save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);
  1910. X
  1911. X    xv_set(save_btn,
  1912. X        PANEL_INACTIVE,        TRUE,
  1913. X        NULL);
  1914. X    xv_set(save_txt,
  1915. X        PANEL_INACTIVE,        TRUE,
  1916. X        NULL);
  1917. #endif    USE_SAVE
  1918. X    if (!parent)
  1919. X    {
  1920. X        xv_set(bookmark_mi,
  1921. X            MENU_INACTIVE,                    TRUE,
  1922. X            NULL);
  1923. X        xv_set(show_info_mi,
  1924. X            MENU_INACTIVE,                    TRUE,
  1925. X            NULL);
  1926. X    }
  1927. }
  1928. X
  1929. X
  1930. //***************************************************************************
  1931. // void GWDirectory::row_select(int, Response *)
  1932. //
  1933. void GWDirectory::row_select(int, Response *)
  1934. {
  1935. #if        USE_SAVE
  1936. X    //
  1937. X    // Show the button and the text item if the selected item is savable
  1938. X    //
  1939. X    if (strchr("09", resp->get_type()))
  1940. X    {
  1941. X        Panel_item        save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
  1942. X        Panel_item        save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);
  1943. X
  1944. X        xv_set(save_btn,
  1945. X            PANEL_INACTIVE,        FALSE,
  1946. X            NULL);
  1947. X        xv_set(save_txt,
  1948. X            PANEL_INACTIVE,        FALSE,
  1949. X            NULL);
  1950. X    }
  1951. #endif    USE_SAVE
  1952. X    xv_set(show_info_mi,
  1953. X        MENU_INACTIVE,                    FALSE,
  1954. X        NULL);
  1955. X    xv_set(bookmark_mi,
  1956. X        MENU_INACTIVE,                    FALSE,
  1957. X        NULL);
  1958. }
  1959. X
  1960. X
  1961. //***************************************************************************
  1962. // void GWDirectory::display()
  1963. //
  1964. void GWDirectory::display()
  1965. {
  1966. X    gopher->start_get();
  1967. X    int        i = 0;
  1968. X    char    *str;
  1969. X
  1970. X    frame_unbusy(frame);
  1971. X    xv_set(dir_list,
  1972. X        XV_SHOW,                    FALSE,
  1973. X        NULL);
  1974. X    while (str = gopher->get_next())
  1975. X    {
  1976. X        Response    *r = new Response(str);
  1977. X        xv_set(dir_list,
  1978. X            PANEL_LIST_INSERT,            i,
  1979. X            PANEL_LIST_STRING,            i, r->get_title(),
  1980. X            PANEL_LIST_GLYPH,            i, get_image(r->get_type()),
  1981. X            PANEL_LIST_CLIENT_DATA,        i, r,
  1982. X            NULL);
  1983. X        i++;
  1984. X    }
  1985. X    xv_set(dir_list,
  1986. X        XV_SHOW,                    TRUE,
  1987. X        NULL);
  1988. }
  1989. X
  1990. X
  1991. #if        USE_SAVE
  1992. //***************************************************************************
  1993. // void GWDirectory::save_notify(Panel_item item, Event *event)
  1994. //
  1995. void GWDirectory::save_notify(Panel_item item, Event *event)
  1996. {
  1997. X    event = event;
  1998. X    GWDirectory        *gwindow = (GWDirectory *) xv_get(item, XV_KEY_DATA, KEY_GWINDOW);
  1999. X    Panel_item        save_txt = (Panel_item) xv_get(item, XV_KEY_DATA, KEY_SAVE_TXT);
  2000. X
  2001. X    char    *filename = (char *) xv_get(save_txt, PANEL_VALUE);
  2002. }
  2003. #endif    USE_SAVE
  2004. X
  2005. X
  2006. //***************************************************************************
  2007. // void GWDirectory::menu_proc(Menu menu, Menu_item mi)
  2008. //
  2009. void GWDirectory::menu_proc(Menu menu, Menu_item mi)
  2010. {
  2011. X    GWDirectory        *gwindow = (GWDirectory *) xv_get(menu, XV_KEY_DATA, KEY_GWINDOW);
  2012. X    char            *item = (char *) xv_get(mi, MENU_STRING);
  2013. X
  2014. X    if (strcmp(item, "Bookmarks...") == 0)
  2015. X    {
  2016. X        bookmarks->show();
  2017. X    }
  2018. X    else if (strcmp(item, "Preferences...") == 0)
  2019. X    {
  2020. X        //
  2021. X        // Build a preferences window
  2022. X        //
  2023. X        gwpref->show();
  2024. X    }
  2025. X    else if (strcmp(item, "About...") == 0)
  2026. X    {
  2027. X        //
  2028. X        // Build an About window
  2029. X        //
  2030. X        GWAbout    *about = new GWAbout(gwindow->frame);
  2031. X        about->open(NULL);
  2032. X    }
  2033. X    else if (strcmp(item, "Another Gopher...") == 0)
  2034. X    {
  2035. X        //
  2036. X        // Get information from the user about where to contact
  2037. X        // a new gopher server.
  2038. X        //
  2039. X        GWGopher    *newgopher = new GWGopher(gwindow->frame);
  2040. X        newgopher->open(gwindow->info);
  2041. X    }
  2042. }
  2043. X
  2044. X
  2045. //***************************************************************************
  2046. // void GWDirectory::set_bookmark_proc(Menu menu, Menu_item mi)
  2047. //
  2048. void GWDirectory::set_bookmark_proc(Menu menu, Menu_item mi)
  2049. {
  2050. X    GWDirectory        *gwindow = (GWDirectory *) xv_get(mi, XV_KEY_DATA, KEY_GWINDOW);
  2051. X
  2052. X    menu = menu;
  2053. X    if (gwindow->current_selected == -1)
  2054. X    {
  2055. X        //
  2056. X        // No row is selected.  We will assume we want to add a bookmark pointing to the
  2057. X        // current directory.  This is simple since we already have a Response object
  2058. X        // for ourselves.
  2059. X        //
  2060. X        bookmarks->add(new Response(gwindow->info));
  2061. X    }
  2062. X    else
  2063. X    {
  2064. X        //
  2065. X        // Some row was selected.  This is cool.  All we need to do now is retrieve the
  2066. X        // data associated with that row and add it to the bookmark list.
  2067. X        //
  2068. X        Response        *r;
  2069. X        r = (Response *) xv_get(gwindow->dir_list, PANEL_LIST_CLIENT_DATA, gwindow->current_selected);
  2070. X        bookmarks->add(new Response(r));
  2071. X    }
  2072. }
  2073. X
  2074. X
  2075. X
  2076. SHAR_EOF
  2077. chmod 0664 GWDirectory.cc ||
  2078. echo 'restore of GWDirectory.cc failed'
  2079. Wc_c="`wc -c < 'GWDirectory.cc'`"
  2080. test 9592 -eq "$Wc_c" ||
  2081.     echo 'GWDirectory.cc: original size 9592, current size' "$Wc_c"
  2082. fi
  2083. true || echo 'restore of GWDownload.cc failed'
  2084. echo End of part 1, continue with part 2
  2085. exit 0
  2086.